package cn.barudisshu.cglib.transaction;

import cn.barudisshu.Transaction;
import cn.barudisshu.TransactionAdapter;
import cn.barudisshu.TransactionAnn;
import cn.barudisshu.cglib.AOPInterceptor;

import java.lang.reflect.Method;

/**
 * @author Barudisshu
 */
public class TransactionCglib implements AOPInterceptor {

    private Transaction transaction;

    @Override
    public void before(Method method, Object[] args) {
        if (isRequiresNew(method)) {
            transaction = new TransactionAdapter();
            transaction.open();
        }
    }

    @Override
    public void after(Method method, Object[] args) {
        if (transaction != null) {
            transaction.commit();
        }
    }

    @Override
    public void afterThrowing(Method method, Object[] args, Throwable throwable) {
        if (transaction != null) {
            transaction.rollBack();
        }
    }

    @Override
    public void afterFinally(Method method, Object[] args) {
        if (transaction != null) {
            transaction.closeIfStillOpen();
            transaction = null;
        }
    }

    protected boolean isRequiresNew(Method method) {
        TransactionAnn transactionAnnotation = method.getAnnotation(TransactionAnn.class);

        if (transactionAnnotation != null) {
            if ("REQUIRES_NEW".equals(transactionAnnotation.value())) {
                return true;
            }
        }

        return false;
    }
}
